<?php

namespace common\observer;

use common\model\TaskModel;
use support\SingletonTrait;
use common\service\TaskService;
use common\service\CommonService;
use common\service\StatusService;
use teamones\dbeventObserver\interfaces\SplSubject;
use teamones\dbeventObserver\interfaces\SplObserver;

/**
 * 监听任务开始和完成和待发布 同步到分类任务
 */
class StatusSyncToParentStepCategoryTask implements SplObserver
{
    use SingletonTrait;

    /**
     * @inheritDoc
     */
    function update(SplSubject $subject): void
    {
        $updateData = $subject->getSplUpdateData();
        if (!isset($updateData['task_status'])) {
            return;
        }
        $task = $subject->getSubjectData();

        $statusService = StatusService::getInstance();
        $startStatus = $statusService->getTaskDefaultStartStatus();
        $doneStatus = $statusService->getTaskDoneStatus();
        $closedStatus = $statusService->getTaskDefaultClosedStatus();
        $waitPublishStatus = $statusService->getTaskReadyToPublishStatus();
        $parentTask = TaskService::getInstance()->getParentTask($task['id'], $task['project_id']);
        if (empty($parentTask)) {
            return;
        }
        if (!in_array($updateData['task_status'], [$startStatus['id'], $doneStatus['id'], $waitPublishStatus['id'], $closedStatus['id']])) {
            return;
        }
        $parentTaskJson = json_decode($parentTask['json'], true);
        $parentTaskStatus = $parentTaskJson['task_status'] ?? "";

        //分类任务和工序任务状态一样 跳过
        if ($parentTaskStatus == $updateData['task_status']) {
            APP_DEBUG && trace("The status of stepCategory task is the same as that of step task", "DEBUG");
            return;
        }

        //@update 2021年3月19日 只需要检查当前工序流 当前环节里最后一个工序任务是否也为更新状态
        if (in_array($updateData['task_status'], [$doneStatus['id'], $waitPublishStatus['id']])) {
            $latestTask = model(TaskModel::class)
                ->where([
                    'step_category_id' => $task['step_category_id'],
                    'entity_id' => $task['entity_id'],
                    'step_type' => 'step',
                ])
                ->where("JSON_UNQUOTE(JSON_EXTRACT(json,'$.is_dismantle_task')) is null")
                ->field('JSON_UNQUOTE(JSON_EXTRACT(json,\'$.task_status\')) as task_status')
                ->order('pre_task_id DESC,id DESC')
                ->find();
            // 存在工序任务 并且最后一个工序任务没有完成
            if (!empty($latestTask) && $latestTask['task_status'] != $updateData['task_status']) {
                APP_DEBUG && trace("latest task not same skip status write", "DEBUG");
                return;
            }
        } else if ($updateData['task_status'] == $closedStatus['id']) {
            // 任务被废除 查询最后一个没有取消的任务
            $latestTask = model(TaskModel::class)
                ->where([
                    'step_category_id' => $task['step_category_id'],
                    'entity_id' => $task['entity_id'],
                    'step_type' => 'step',
                ])
                ->where("json->>'$.task_status' <> " . $closedStatus['id'])
                ->field('JSON_UNQUOTE(JSON_EXTRACT(json,\'$.task_status\')) as task_status')
                ->order('pre_task_id DESC,id DESC')
                ->find();
            // 存在工序任务 并且最后一个工序任务没有完成
            if (!empty($latestTask) && $latestTask['task_status'] != $updateData['task_status']) {
                APP_DEBUG && trace("latest task not same skip status write", "DEBUG");
                return;
            }
        }

        // 更新任务状态
        $parentUpdateData = [
            'id' => $parentTask['id'],
            'task_status' => $updateData['task_status'],
        ];
        try {
            CommonService::instance('task')->update($parentUpdateData, 'task', false);
        } catch (\Throwable $e) {
            trace(format_exception_info($e), 'ERR');
        }

    }
}
